Back to Blog Tutorial

Building a Data Form: Using a HTML Structure and SQL.

Wondering how to get Contacts data saved and updated in the database? Here's how the forms that do both actually work.

Jun 2005·7 min read·Post 6 of 8

Here's the form itself — the input fields, the validation, the layout.

1 ADDING A NEW CONTACT

This is the input block itself — the fields, the validation, the footer buttons. Trimmed to the fields that matter:

emxml_ajxInpFcontact.xml
<Block tag='div'>

          <Element type='form'>
          <Form id='addcontactform' Name='ADDCONTACT' Method="POST"
            enctype="multipart/form-data" OnSubmit='validate_form()'>
          <Action><![CDATA[javascript:setupaddcontactform()]]></Action>
          <HiddenFields>
              <Input type='hidden' name='submod' value='insertcontact' />
          </HiddenFields>
          <Valscript>emxml_Scrdefault.xml</Valscript>
          <FormPanel type='Singlepage'/>
          </Form>

          <Element type='inlinecontainer' tag='div'>
          <Attributes class='modal-body' />
          <Element type='formtables'>
              <n>ft1</n>
              <FormPage>ft1</FormPage>
              <Table id='ft1' class='table'>
                  <Row><Col>
                      <Element type='htmlforminput' tag='input'>
                          <Attributes id='contact_name' name='contact_name' placeholder='Full name' />
                          <Validation><Validate type="mandatory" tmplt="tmp1">Name is required</Validate></Validation>
                      </Element>
                  </Col></Row>
                  <Row><Col>
                      <Element type='htmlforminput' tag='input'>
                          <Attributes id='email' name='email' placeholder='Email address' />
                          <Validation><Validate type="mandatory" tmplt="tmp1">Email is required</Validate></Validation>
                      </Element>
                  </Col></Row>
                  <!-- department, job_title, phone follow the same pattern -->
              </Table>
          </Element>
        </Element>

        <!-- Footer inside <Element type='form'> so validation/submit stay wired -->
        <Element type='inlinecontainer' tag='div'>
            <Attributes class='modal-footer' />
            <Element type='htmlitem' tag='button'>
                <Attributes type='button' class='btn-ghost' onclick="bcModal.close('bcmodaloverlay')" />
                <Text>Cancel</Text>
            </Element>
            <Element type='htmlitem' tag='button'>
                <Attributes type='submit' class='btn-primary' />
                <Text>Save Contact</Text>
            </Element>
        </Element>
        </Element>

        </Block>
<Block> root
Modal input files always root at <Block tag='div'>, with <Element type='form'> nested inside — same rule as every other block file in this arc.
type='submit', no onclick
This is what fires OnSubmit='validate_form()' automatically. Adding an onclick here would either skip validation or fire the submit twice — the Cancel button is the only one that needs a manual onclick, because it just closes the modal.
mandatory validation
Declared per field, in the field itself — not a separate validation function you write and keep in sync with the form.
hidden submod
Tells the engine which processor block handles this submission — the piece post 7 builds.
2 Updating an existing contact

Updating one is different — the form needs to display the current record before anything can be changed. That's where a form's own SQL block comes in, and the same applies to any form that needs to show existing data, not just this one.

emxml_ajxUpdFcontact.xml
<Block tag='div'>
 
          <Element type='form'>
          <Form id='editcontactform' Name='EDITCONTACT' Method="POST"
                 enctype="multipart/form-data" OnSubmit='validate_form()'>
              <Action><![CDATA[javascript:setupeditcontactform()]]></Action>
              <HiddenFields>
                  <Input type='hidden' name='submod' value='updatecontact' />
                  <Input type='hidden' name='contact_id' value='%contact_id%' />
              </HiddenFields>
              <Valscript>emxml_Scrdefault.xml</Valscript>
              <FormPanel type='Singlepage'/>
          </Form>
       
          <Element type='inlinecontainer' tag='div'>
              <Attributes class='modal-body' />
              <Element type='formtables'>
                  <n>ft1</n>
                  <FormPage>ft1</FormPage>
                  <Table id='ft1' class='table'>
                      <Row><Col>
                          <Element type='htmlforminput' tag='input'>
                              <Attributes id='contact_name' name='contact_name' value='%contact_name%' />
                              <Validation><Validate type="mandatory" tmplt="tmp1">Name is required</Validate></Validation>
                          </Element>
                      </Col></Row>
                      <Row><Col>
                          <Element type='htmlforminput' tag='input'>
                              <Attributes id='email' name='email' value='%email%' />
                              <Validation><Validate type="mandatory" tmplt="tmp1">Email is required</Validate></Validation>
                          </Element>
                      </Col></Row>
                      <!-- department, phone follow the same pattern, each pre-filled with its own %token% -->
                  </Table>
              </Element>
          </Element>
       
          <Element type='inlinecontainer' tag='div'>
              <Attributes class='modal-footer' />
              <Element type='htmlitem' tag='button'>
                  <Attributes type='button' class='btn-ghost' onclick="bcModal.close('bcmodaloverlay')" />
                  <Text>Cancel</Text>
              </Element>
              <Element type='htmlitem' tag='button'>
                  <Attributes type='submit' class='btn-primary' />
                  <Text>Save Changes</Text>
              </Element>
          </Element>
          </Element>
       
          <!-- runs once, before the form renders, so every field opens pre-filled -->
          <SQL>
              <query name='contact_prefill'>
                  <![CDATA[
                      SELECT contact_name, email, department, phone
                      FROM   contacts
                      WHERE  contact_id = '%contact_id%'
                      AND    dept_id = '%deptid%'
                      LIMIT  1
                  ]]>
              </query>
          </SQL>
       
        </Block>
<SQL> at the end
Same rule as post 5's detail screen — a single-row query, run once, before anything renders.
value='%token%'
Every field's starting value comes straight from that query — %contact_name%, %email%, and so on are filled in before the form ever reaches the browser, so the user sees their existing data, not empty boxes.
hidden contact_id
Doing double duty — it's what the prefill query filters on (WHERE contact_id = '%contact_id%'), and it travels back out with the submission too, so the processor in the next post knows which row to update rather than insert.
Validation is declared per field, right where it lives — not written separately and kept in sync by hand.
3 Rendered live
app.example.com/manager/contacts

And the Edit form, opened for an existing contact — every field already filled in by the prefill query above:

app.example.com/manager/contacts/1042

Click Save on either form right now and nothing happens — there's no processor behind either one yet. That's deliberate: the next post is entirely about what submod='insertcontact' and submod='updatecontact' actually route to, and what "Save" needs to do once it's clicked.